package com.husd.framework.awarlmart;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.husd.framework.ddl.AutoCodeUtil;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * @author shengdonghu@126.com
 * @date 2023/10/19 10:44
 */
public class WarlmartApiPT {

    final String ptName;
    String ptName2; // 去了空格
    JSONObject root;
    Set<String> requiredSet;
    String comments;
    String examples;
    String description;
    String additionalProperties;
    String type;
    String title;
    String propertiesStr;

    String prePath = "";

    int sheetIndex = 0;

    JSONArray allOfArray;

    Map<String, String> conditionMap = new HashMap<>();

    Stack<WarlmartApiPT> stack = new Stack<>();

    private String key;

    public WarlmartApiPT(String prePath, String key, String ptName, String properties,
                         JSONArray requiredArray,
                         JSONArray allOfArray) {
        this.key = key;
        this.ptName = ptName;
        this.ptName2 = ptName.replaceAll(" ", "_");
        this.propertiesStr = properties;
        this.root = JSONObject.parseObject(propertiesStr);
        this.requiredSet = createRequiredSet(requiredArray);

        this.comments = this.root.getString("comments");
        this.examples = this.root.getString("examples");
        this.description = this.root.getString("description");
        this.additionalProperties = this.root.getString("additionalProperties");
        this.type = this.root.getString("type");
        this.title = this.root.getString("title");
        this.prePath = prePath;
        this.allOfArray = allOfArray;
        initConditionMap();
    }

    private void initConditionMap() {

        // 读取allOf 查看是不是可选的必填项
        //     {
        //      "then": {
        //        "required": [
        //          "warrantyURL"
        //        ]
        //      },
        //      "if": {
        //        "properties": {
        //          "has_written_warranty": {
        //            "type": "string",
        //            "enum": [
        //              "Yes - Warranty URL"
        //            ]
        //          }
        //        },
        //        "required": [
        //          "has_written_warranty"
        //        ]
        //      }
        //    },
        if (allOfArray != null) {
            for (int j = 0; j < allOfArray.size(); j++) {
                JSONObject jsonObject = allOfArray.getJSONObject(j);
                String then = jsonObject.getJSONObject("then").getJSONArray("required").getString(0);
                JSONArray colList = jsonObject.getJSONObject("if").getJSONArray("required");
                StringBuilder sb = new StringBuilder();
                sb.append(" 如果 ");
                for (int z = 0; z < colList.size(); z++) {
                    String col = colList.getString(z);
                    sb.append(" ").append(" 字段：").append(col).append(" ");
                    JSONObject valObjP = jsonObject.getJSONObject("if")
                            .getJSONObject("properties");
                    String val = "";
                    if (valObjP == null) {
                        val = jsonObject.getJSONObject("if").getJSONArray("required").toJSONString();
                        val = val + " 有值 ";
                    } else {
                        sb.append(" 的值是:");
                        JSONObject valObj = valObjP.getJSONObject(col);
                        if (valObj != null) {
                            val = valObj.getString("enum");
                        } else {
                            throw new RuntimeException(valObj.toJSONString());
                        }
                    }
                    sb.append(" ").append(val);
                }
                sb.append(" ").append(" 那么 ").append(then).append(" 是必填项 \n ");
                this.conditionMap.put(then, sb.toString());
            }
        }

    }

    private Set<String> createRequiredSet(JSONArray requiredArray) {

        Set<String> set = new HashSet<>();
        if (requiredArray == null) {
            return set;
        }
        for (int i = 0; i < requiredArray.size(); i++) {
            set.add(requiredArray.getString(i));
        }
        return set;
    }

    public List<WarlmartSheet> convert() {

        System.out.println("开始处理元素: " + this.key);
        List<WarlmartSheet> res = new ArrayList<>();

        List<WarlmartApiExcelRow> current = new ArrayList<>();

        Set<Map.Entry<String, Object>> entrySet = this.root.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            String key = entry.getKey();
            Object val = entry.getValue();
            JSONObject valObj = (JSONObject) val;
            WarlmartApiExcelRow row = convert2Row(key, valObj);
            current.add(row);
        }

        String sheetName = StringUtils.isBlank(prePath) ? "主文档" : prePath;
        res.add(new WarlmartSheet(sheetName, current));

        while (stack.isEmpty() == false) {
            WarlmartApiPT www = this.stack.pop();
            List<WarlmartSheet> nextSheet = www.convert();
            // 把这个写入到下一个sheet中
            res.addAll(nextSheet);
        }
        return res;
    }

    private void write2ExcelFile(String ptName2, List<WarlmartApiExcelRow> res, int sheetIndex) {

        this.sheetIndex++;
    }

    private WarlmartApiExcelRow convert2Row(String name, JSONObject valObj) {

        WarlmartApiExcelRow warlmartApiExcelRow = new WarlmartApiExcelRow();
        warlmartApiExcelRow.setName(name);
        String type = valObj.getString("type");
        type = type.toLowerCase();
        switch (type) {
            case "string":
                warlmartApiExcelRow = convert2Row4String(type, name, valObj);
                break;
            case "array":
                warlmartApiExcelRow = convert2Row4Array(type, name, valObj);
                break;
            case "object":
                warlmartApiExcelRow = convert2Row4Object(type, name, valObj);
                break;
            case "integer":
                warlmartApiExcelRow = convert2Row4Integer(type, name, valObj);
                break;
            case "number":
                warlmartApiExcelRow = convert2Row4Number(type, name, valObj);
                break;
            default:
                throw new RuntimeException("不识别的type:" + type + " val:" + propertiesStr);
        }
        return warlmartApiExcelRow;
    }

    private WarlmartApiExcelRow convert2Row4Number(String type, String name, JSONObject valObj) {

        WarlmartApiExcelRow warlmartApiExcelRow = new WarlmartApiExcelRow();

        warlmartApiExcelRow.setName(name);
        warlmartApiExcelRow.setType(type);

        warlmartApiExcelRow.setTitle(valObj.getString("title"));
        warlmartApiExcelRow.setDescription(valObj.getString("description"));
        warlmartApiExcelRow.setExamples(valObj.getString("examples"));
        warlmartApiExcelRow.setComments(valObj.getString("comments"));

        //  warlmartApiExcelRow.setTitle(title);
        warlmartApiExcelRow.setMin(valObj.getString("minimum"));
        warlmartApiExcelRow.setMax(valObj.getString("maximum"));
        //  warlmartApiExcelRow.setDescription(description);
//        warlmartApiExcelRow.setExamples(examples);
//        warlmartApiExcelRow.setComments(comments);
        warlmartApiExcelRow.setRequired(requiredOrNot(name));
        warlmartApiExcelRow.setAdditionalProperties(this.additionalProperties);
        warlmartApiExcelRow.setRemark("multipleOf 属性:" + valObj.getString("multipleOf"));

        JSONArray enumArr = valObj.getJSONArray("enum");
        // 如果是枚举类型 要设置类型为枚举
        if (enumArr != null && enumArr.size() > 0) {
            warlmartApiExcelRow.setType("枚举2");
            warlmartApiExcelRow.setExamples(enumArr.toString());
        }

        return warlmartApiExcelRow;
    }

    private WarlmartApiExcelRow convert2Row4Integer(String type, String name, JSONObject valObj) {

        WarlmartApiExcelRow warlmartApiExcelRow = new WarlmartApiExcelRow();

        warlmartApiExcelRow.setName(name);
        warlmartApiExcelRow.setType(type);

        warlmartApiExcelRow.setTitle(valObj.getString("title"));
        warlmartApiExcelRow.setDescription(valObj.getString("description"));
        warlmartApiExcelRow.setExamples(valObj.getString("examples"));
        warlmartApiExcelRow.setComments(valObj.getString("comments"));

        //warlmartApiExcelRow.setTitle(title);
        warlmartApiExcelRow.setMin(valObj.getString("minimum"));
        warlmartApiExcelRow.setMax(valObj.getString("maximum"));
//        warlmartApiExcelRow.setDescription(description);
//        warlmartApiExcelRow.setExamples(examples);
//        warlmartApiExcelRow.setComments(comments);
        warlmartApiExcelRow.setRequired(requiredOrNot(name));
        warlmartApiExcelRow.setAdditionalProperties(this.additionalProperties);

        JSONArray enumArr = valObj.getJSONArray("enum");
        // 如果是枚举类型 要设置类型为枚举
        if (enumArr != null && enumArr.size() > 0) {
            warlmartApiExcelRow.setType("枚举2");
            warlmartApiExcelRow.setExamples(enumArr.toString());
        }

        return warlmartApiExcelRow;
    }

    private WarlmartApiExcelRow convert2Row4Object(String type, String name, JSONObject valObj) {
        WarlmartApiExcelRow warlmartApiExcelRow = new WarlmartApiExcelRow();

        warlmartApiExcelRow.setName(name);
        warlmartApiExcelRow.setType(type);
//        warlmartApiExcelRow.setTitle(title);
//        warlmartApiExcelRow.setDescription(description);
//        warlmartApiExcelRow.setExamples(examples);
//        warlmartApiExcelRow.setComments(comments);

        warlmartApiExcelRow.setTitle(valObj.getString("title"));
//        warlmartApiExcelRow.setMin(valObj.getString("minLength"));
//        warlmartApiExcelRow.setMax(valObj.getString("maxLength"));
        warlmartApiExcelRow.setDescription(valObj.getString("description"));
        warlmartApiExcelRow.setExamples(valObj.getString("examples"));
        warlmartApiExcelRow.setComments(valObj.getString("comments"));

        warlmartApiExcelRow.setRequired(requiredOrNot(name));
        warlmartApiExcelRow.setAdditionalProperties(this.additionalProperties);

        StringBuilder sb = new StringBuilder();
        sb.append("object类型 ");
        String nextPath = prePath + AutoCodeUtil.firstUpper(name) + "Object";
        sb.append(" ").append(nextPath);
        String nextContent = valObj.getString("properties");
        WarlmartApiPT ww = new WarlmartApiPT(nextPath, name, name.replaceAll(" ", "_"),
                nextContent, valObj.getJSONArray("required"),
                valObj.getJSONArray("allOf"));
        stack.push(ww);

        return warlmartApiExcelRow;
    }

    private WarlmartApiExcelRow convert2Row4Array(String type, String name, JSONObject valObj) {

        WarlmartApiExcelRow warlmartApiExcelRow = new WarlmartApiExcelRow();

        warlmartApiExcelRow.setName(name);
        warlmartApiExcelRow.setType(type);

        warlmartApiExcelRow.setTitle(valObj.getString("title"));
        warlmartApiExcelRow.setDescription(valObj.getString("description"));
        warlmartApiExcelRow.setExamples(valObj.getString("examples"));
        warlmartApiExcelRow.setComments(valObj.getString("comments"));

        warlmartApiExcelRow.setMin(valObj.getString("minItems"));
        warlmartApiExcelRow.setMax("");
        warlmartApiExcelRow.setRequired(requiredOrNot(name));
        warlmartApiExcelRow.setAdditionalProperties(this.additionalProperties);

        JSONObject arrayItemObj = valObj.getJSONObject("items");
        String arrayItemType = arrayItemObj.getString("type");
        StringBuilder arrayItemsDesc = new StringBuilder();
        switch (arrayItemType) {
            case "string":
                String eee = arrayItemObj.getString("enum");
                if (StringUtils.isNotBlank(eee)) {
                    arrayItemsDesc.append("枚举类型 ")
                            .append("可选值:")
                            .append(eee);
                    arrayItemsDesc.append(" \n");
                } else {
                    arrayItemsDesc.append("字符串类型 最小长度:")
                            .append(arrayItemObj.getString("minLength"))
                            .append(" 最大长度: ").append(arrayItemObj.getString("maxLength"))
                            .append(" 类型:").append(arrayItemObj.getString("type"))
                            .append(" \n");
                }
                break;
            case "object":
                arrayItemsDesc.append("object类型 ");
                String nextPath = prePath + AutoCodeUtil.firstUpper(name) + "ArrayItem";
                arrayItemsDesc.append(" ").append(nextPath);
                WarlmartApiPT ww = new WarlmartApiPT(nextPath, name, name.replaceAll(" ", "_"),
                        arrayItemObj.getString("properties"),
                        arrayItemObj.getJSONArray("required"),
                        arrayItemObj.getJSONArray("allOf")
                );
                stack.push(ww);
                break;
            case "integer":
                arrayItemsDesc.append("integer类型 最小值:")
                        .append(arrayItemObj.getString("minimum"))
                        .append(" 最大值: ").append(arrayItemObj.getString("maximum"))
                        .append(" \n");
                break;
            default:
                throw new RuntimeException("不识别的 arrayItemType: " + arrayItemType);
        }
        warlmartApiExcelRow.setArrayItemsDesc(arrayItemsDesc.toString());
        return warlmartApiExcelRow;
    }

    private WarlmartApiExcelRow convert2Row4Enum(String type,
                                                 String name,
                                                 JSONObject valObj) {

        WarlmartApiExcelRow warlmartApiExcelRow = new WarlmartApiExcelRow();
        warlmartApiExcelRow.setName(name);
        warlmartApiExcelRow.setType(type);


        return warlmartApiExcelRow;
    }

    private WarlmartApiExcelRow convert2Row4String(String type,
                                                   String name,
                                                   JSONObject valObj) {

        WarlmartApiExcelRow warlmartApiExcelRow = new WarlmartApiExcelRow();

        warlmartApiExcelRow.setName(name);
        warlmartApiExcelRow.setType(type);
        warlmartApiExcelRow.setTitle(valObj.getString("title"));
        warlmartApiExcelRow.setMin(valObj.getString("minLength"));
        warlmartApiExcelRow.setMax(valObj.getString("maxLength"));
        warlmartApiExcelRow.setDescription(valObj.getString("description"));
        warlmartApiExcelRow.setExamples(valObj.getString("examples"));
        warlmartApiExcelRow.setComments(valObj.getString("comments"));
        warlmartApiExcelRow.setRequired(requiredOrNot(name));
        warlmartApiExcelRow.setAdditionalProperties(this.additionalProperties);

        JSONArray enumArr = valObj.getJSONArray("enum");
        // 如果是枚举类型 要设置类型为枚举
        if (enumArr != null && enumArr.size() > 0) {
            warlmartApiExcelRow.setType("枚举2");
            warlmartApiExcelRow.setExamples(enumArr.toString());
        }

        return warlmartApiExcelRow;
    }

    private String requiredOrNot(String name) {

        boolean required = this.requiredSet.contains(name);
        if (required) {
            return "必填";
        } else {
            String condition = this.conditionMap.get(name);
            if (StringUtils.isNotBlank(condition)) {
                return condition;
            }
            return "可选";
        }
    }

    private String getAdditionalProperties() {

        return String.valueOf(root.getBoolean("additionalProperties"));
    }
}
